﻿#define 作弊
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace MaJiang{
	public class MJ_Comman{
		public static string[] CardName = new string[]{"万","条","饼","花","剑","风"};
		public static string[] CardHuaName = new string[]{"春花","夏花","秋花","冬花","梅花","兰花","竹花","菊花"};
		public static string[] CardNumberName = new string[]{"一","二","三","四","五","六","七","八","九"};
		public static string[] CardJianName = new string[]{"红中","发财","白板"};
		public static string[] CardFengName = new string[]{"东风","西风","南风","北风"};
		public static DeskCardConf conf = new DeskCardConf();
	}
	public class DeskCardConf{
		public bool NoWan = false;	
		public bool NoBing = false;
		public bool NoTiao = false;
		public bool NoHua = false;
		public bool NoJian = false;
		public bool NoFeng = false;
	}
	public enum enCradType{
		/// <summary>
		/// 万1-9
		/// </summary>
		Wan = 0,
		/// <summary>
		/// 条1-9
		/// </summary>
		Tiao = 1,
		/// <summary>
		/// 饼1-9
		/// </summary>
		Bing,
		/// <summary>
		/// 1春2夏3秋4冬5梅6兰7竹8菊
		/// </summary>
		Hua,
		/// <summary>
		/// 1中2发3白
		/// </summary>
		Jian,
		/// <summary>
		/// 1东2西3南4北
		/// </summary>
		Feng,
		Count,
	}

	public struct Card{
		public enCradType type;
		/// <summary>
		/// 不可做索引，索引使用index
		/// </summary>
		public int id;
		public Card(enCradType _type,int _id){
			type = _type;
			id = _id;
		}	
		public int index{
			get{
				return id - 1;
			}
		}
		public string CardName{
			get{
				var _name = "无";
				if ((int)type <= (int)enCradType.Bing) {
					_name = MJ_Comman.CardNumberName[index] + MJ_Comman.CardName [(int)type];
				} else {
					switch(type){
					case enCradType.Hua:
						_name = MJ_Comman.CardHuaName [index];
						break;
					case enCradType.Jian:
						_name = MJ_Comman.CardJianName [index];
						break;
					case enCradType.Feng:
						_name = MJ_Comman.CardFengName [index];
						break;
					}
				}
				return "["+_name+"]";
			}
		}
		public bool isLikeType(enCradType _type){
			return type == _type;
		}
		public bool isLikeTypes(enCradType[] _types){
			for (var i = 0; i < _types.Length; i++) {
				if(isLikeType(_types[i]))
					return true;
			}
			return false;
		}
	}

	/// <summary>
	/// 牌组
	/// </summary>
	public class CardDeck{
		public List<Card> cards = new List<Card>();
		/// <summary>
		/// 清空牌组
		/// </summary>
		public virtual void ClearCard(){
			cards.Clear ();
		}
		public int CardCount{
			get{
				return cards.Count;
			}
		}
		protected void AddCard(enCradType type,int id,int number = 1){
			for (var i = 0; i < number; i++) {
				cards.Add (new Card (type, id));
			}
		}
		protected void AddCard(Card card,int number = 1){
			for (var i = 0; i < number; i++) {
				cards.Add (card);
			}
		}
		public void AddCards(List<Card> _cards){
			cards.AddRange (_cards);
		}
		public List<Card> getCardsByTypes(enCradType[] types){
			var cardGroup = new List<Card> ();
			for (var i = 0; i < types.Length; i++) {
				cardGroup.AddRange (getCardsByType (types [i]));	
			}
			return cardGroup;
		}
		public List<Card> getCardsByType(enCradType type){
			var cardGroup = new List<Card> ();
			for (var i = 0; i < cards.Count; i++) {
				if (cards [i].type == type)
					cardGroup.Add (cards [i]);
			}
			return cardGroup;
		}
		/// <summary>
		/// 整理牌面
		/// </summary>
		public void SortCards(){	
			var list = new List<Card> ();
			for (var i = 0; i < (int)enCradType.Count; i++) {
				var typeCards = getCardsByType ((enCradType)i);		
				typeCards.Sort (MaJiangTool.sortCard);
				list.AddRange (typeCards);
			}
			cards = list;
		}
	}

	/// <summary>
	/// 桌上的牌
	/// </summary>
	public class DeskCards:CardDeck{
		/// <summary>
		/// 自定义洗牌
		/// </summary>
		public System.Action<DeskCards> onMakeCard;
		public void CreateCards(){
			//清掉现在的牌
			ClearCard ();
			//先制造牌
			MakeCard ();
			//紧接着洗牌
			Shuffle ();
		}
		void MakeCard(){
			if (onMakeCard != null) {
				onMakeCard (this);
				return;
			}
			if(!MJ_Comman.conf.NoWan)
				AddCardGroup (enCradType.Wan, 9, 4);
			if(!MJ_Comman.conf.NoBing)
				AddCardGroup (enCradType.Bing, 9, 4);
			if(!MJ_Comman.conf.NoTiao)
				AddCardGroup (enCradType.Tiao, 9, 4);
			if(!MJ_Comman.conf.NoHua)
				AddCardGroup (enCradType.Hua, 8, 1);
			if(!MJ_Comman.conf.NoJian)
				AddCardGroup (enCradType.Jian, 3, 4);
			if(!MJ_Comman.conf.NoFeng)
				AddCardGroup (enCradType.Feng, 4, 4);
		}
		void Shuffle(){
			List<Card> newcards = new List<Card> ();
			while (cards.Count > 0) {
				int r = Random.Range (0, cards.Count);
				newcards.Add (cards [r]);
				cards.RemoveAt (r);
			}
			cards = newcards;
		}

		void AddCardGroup(enCradType type,int maxId,int number){
			for (var i = 1; i <= maxId; i++) {	
				AddCard (type, i, number);
			}
		}
	}

	/// <summary>
	/// 弃牌堆
	/// </summary>
	public class Discard:CardDeck{
		
	}

	/// <summary>
	/// 玩家的牌组
	/// </summary>
	public class PlayerCards:CardDeck{
		/// <summary>
		/// 是否是庄家
		/// </summary>
		public bool isBanker;
		public int index;
		public string indexName{
			get{
				return (index + 1) + "号玩家";
			}
		}
		/// <summary>
		/// 花牌堆
		/// </summary>
		public List<Card> huaCards = new List<Card> ();
		/// <summary>
		/// 摸排
		/// </summary>
		public void TouchCard(Card card){
			cards.Add (card);
		}
		/// <summary>
		/// 从当前排堆吧花牌丢到花牌对里
		/// </summary>
		/// <param name="_huaCards">Hua cards.</param>
		public void DisHuaCards(List<Card> _huaCards){
			for (var i = 0; i < _huaCards.Count; i++) {
				if (cards.Contains (_huaCards [i])) {
					cards.Remove (_huaCards [i]);
					huaCards.Add (_huaCards [i]);
				}
			}
		}
		/// <summary>
		/// 直接添加到花牌堆 比如开金花牌
		/// </summary>
		public void AddHuaCard(Card _huaCard){
			huaCards.Add (_huaCard);
		}
		public override void ClearCard ()
		{
			base.ClearCard ();
			huaCards.Clear ();
		}
	}

	/// <summary>
	/// 牌组管理器
	/// </summary>
	public class CardManager{
		public bool isInit;
		/// <summary>
		/// 是否是第一局
		/// </summary>
		public bool isFirstGame{
			get{
				return turnCount == 1;
			}
		}
		public MJ_Command shuffle;
		/// <summary>
		/// 万能牌
		/// </summary>
		public Card wildCard;
		/// <summary>
		/// 是否存在庄家
		/// </summary>
		/// <value><c>true</c> if has banker; otherwise, <c>false</c>.</value>
		public bool hasBanker{
			get{
				return _bankerIndex >= 0;
			}
		}
		/// <summary>
		/// 庄家索引
		/// </summary>
		int _bankerIndex;
		public void SetBanker(int _id){
			if (banker != null)
				banker.isBanker = false;
			_bankerIndex = _id;
			if(banker != null)
				banker.isBanker = true;
		}
		/// <summary>
		/// 庄家
		/// </summary>
		/// <value>The backer.</value>
		public PlayerCards banker{
			get{
				if (_bankerIndex >= 0 && _bankerIndex < players.Length)
					return players [_bankerIndex];
				else
					return null;
			}
		}
		/// <summary>
		/// 当前的玩家
		/// </summary>
		/// <value>The current touch player.</value>
		public PlayerCards currentTouchPlayer{
			get{
				if (touchPlayerIndex >= 0 && touchPlayerIndex < players.Length)
					return players [touchPlayerIndex];
				return null;
			}
		}
		/// <summary>
		/// 是否选好摸排的
		/// </summary>
		/// <value><c>true</c> if has first touch player; otherwise, <c>false</c>.</value>
		public bool hasFirstTouchPlayer{
			get{
				return touchPlayerIndex >= 0;
			}
		}
		/// <summary>
		/// 盘数
		/// </summary>
		public int turnCount;
		/// <summary>
		/// 游戏中的回合数
		/// </summary>
		public int gameTurnCount;
		/// <summary>
		/// 摸牌的玩家
		/// </summary>
		public int touchPlayerIndex;
		/// <summary>
		/// 初始摇骰子
		/// </summary>
		public int[] firstRandomCardIndex;
		/// <summary>
		/// 牌桌
		/// </summary>
		public DeskCards desk;
		/// <summary>
		/// 赌客
		/// </summary>
		public PlayerCards[] players;
		/// <summary>
		/// 下一张牌
		/// </summary>
		public int nextCardId;
		/// <summary>
		/// 上一张牌
		/// </summary>
		public int backCardId;
		/// <summary>
		/// 弃牌堆
		/// </summary>
		public Discard discard;
		/// <summary>
		/// 被使用的牌数
		/// </summary>
		public int useCards;
		/// <summary>
		/// 剩余牌数
		/// </summary>
		/// <value>The surplus card count.</value>
		public int surplusCardCount{
			get{
				return desk.cards.Count - useCards;
			}
		}
		public HuPaiData huPaiData;
		/// <summary>
		/// 胡牌器
		/// </summary>
		public HuPaiMgr huPaiMgr;
		/// <summary>
		/// 日记
		/// </summary>
		public MJ_DaskLog logMgr = new MJ_DaskLog ();
		MJ_CommandMgr mgr;
		public CardManager(){
			mgr = new MJ_CommandMgr (this);
			huPaiMgr = new HuPaiMgr (this);
			desk = new DeskCards ();
			discard = new Discard ();
			players = new PlayerCards[4];
			gameTurnCount = 1;
			SetBanker (-1);
			turnCount = 1;
			isInit = false;
			for (var i = 0; i < players.Length; i++) {
				players [i] = new PlayerCards ();
				players [i].index = i;
			}

		}
		#region BaseAction
		/// <summary>
		/// 设置胡牌玩法
		/// </summary>
		/// <param name="wanfa">Wanfa.</param>
		public void SetHuPaiWanFa(HuPaiWanFa wanfa){
			huPaiMgr.SetHuPaiWanFa (wanfa);
		}
		public void SetShuffle(MJ_Command _shuffle){
			shuffle = _shuffle;
			isInit = true;
		}
		/// <summary>
		/// 一盘开始
		/// </summary>
		public void TurnStrt(){
			mgr.ClearCommand ();
			mgr.AddCommand (shuffle);
			mgr.DoCommand ();
		}
		/// <summary>
		/// 一盘结束
		/// </summary>
		public void TurnFinish(){
			turnCount++;
		}
		/// <summary>
		/// 从头开始
		/// </summary>
		public void TurnRest(){
			turnCount = 1;
		}
		/// <summary>
		/// 默认洗牌 不管啥玩法都需要做的
		/// </summary>
		public void DefaultShuffle(){
			Debug.Log ("清理数据");
			//清理日记
			logMgr.Clear ();
			//清理弃牌堆
			discard.ClearCard ();
			//清理玩家手牌
			for (var i = 0; i < players.Length; i++) {
				players [i].ClearCard ();
			}
			//牌桌生成牌组
			desk.CreateCards ();
			touchPlayerIndex = -1;
			firstRandomCardIndex = null;
			useCards = 0;
			turnCount = 1;
		}
		/// <summary>
		/// 下一个玩家回合
		/// </summary>
		public void NextTouchPlayerTurn(){
			NextPlayerIndex (ref touchPlayerIndex);
		}
		/// <summary>
		/// 摸上一张牌
		/// </summary>
		/// <returns>The back card.</returns>
		public Card TouchBackCard(){
			backCardId--;
			if (backCardId < 0)
				backCardId = desk.cards.Count - 1;
			if (backCardId >= desk.cards.Count)
				backCardId -= desk.cards.Count;
			return TouchCard (backCardId);
		}
		/// <summary>
		/// 膜下一张牌
		/// </summary>
		/// <returns>The next card.</returns>
		public Card TouchNextCard(){
			nextCardId++;
			if (nextCardId >= desk.cards.Count)
				nextCardId = 0;
			if (nextCardId < 0)
				nextCardId += desk.cards.Count;
			return TouchCard(nextCardId);
		}
		/// <summary>
		/// 获取制定玩家的下家Id		/// </summary>
		/// <param name="id">Identifier.</param>
		public void NextPlayerIndex(ref int index){
			index = index + 1;
			if (index >= 4)
				index = 0;
		}
		Card TouchCard(int id){
			if (id < 0 || id >= desk.cards.Count) {
				Debug.Log (string.Format ("警告!摸排错误,数组越界{0}", id));
			}
			useCards++;
			return desk.cards [id];
		}
		#endregion

		#region Command
		public void ClearCommand(){
			mgr.ClearCommand ();
		}
		public void AddCommand(MJ_Command cmd){
			mgr.AddCommand (cmd);
		}
		public T AddCommand<T>()where T:MJ_Command,new(){
			return mgr.AddCommand<T> ();
		}
		/// <summary>
		/// 不经过管理器直接执行的命令
		/// </summary>
		/// <param name="cmd">Cmd.</param>
		public void DoCommand(MJ_Command cmd){
			cmd.SetMgr (this);
			cmd.Do ();
		}
		public string getCurrentCMDName(){
			return mgr.getCurrentCMDName ();
		}
		public void DoCurrentCMD(){
			mgr.DoCommand ();
		}	
		public void Update(float dt){
			mgr.Update (dt);
		}
		#endregion

		#region HuPai
		public T AddHuPai<T>()where T:HuPaiBase,new(){
			T t = new T ();
			AddHuPai (t);
			return t;
		}
		public void AddHuPai(HuPaiBase hupai){
			huPaiMgr.AddHuPai (hupai);
		}
		public bool IsCanHuByPlayer(PlayerCards player){
			huPaiData = huPaiMgr.TryHuPai (player);
			return huPaiData.canHu;
		}
		public bool IsCanHuByCurrentPlayer(){
			return IsCanHuByPlayer(players[touchPlayerIndex]);
		}

		#endregion
		#region 作弊
		#if 作弊
		public List<Card> getDeskCards(){
			return desk.cards;
		}
		#endif
		#endregion
	}

}